use super::cache::{
    get_peer_connection, peer_connection_exist, push_peer_connection, update_peer_connection,
    PeerConnection, PeerConnectionState,
};
use crate::{
    signaling::send_string,
    transport::webrtc::{
        get_local_description_string, new_answer_connection, new_offer_connection,
        set_remote_description_by_string,
    },
};

use std::sync::{Arc, Mutex};

pub async fn create_accept_channel(
    remote_peer_id: &String,
    remote_candidates: &Vec<String>,
    remote_local_description: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    //判断是否为自己
    if crate::is_self(remote_peer_id)? {
        return Err(anyhow::anyhow!("不允许本节点自身操作!"));
    }
    //判断是否存在
    let exist = peer_connection_exist(remote_peer_id)?;
    if exist {
        return Ok(get_peer_connection(remote_peer_id)?);
    }
    //新建
    let peer_connection =
        _create_accept_channel(remote_peer_id, remote_candidates, remote_local_description).await?;

    //插入
    push_peer_connection(remote_peer_id, peer_connection.clone())?;

    Ok(peer_connection)
}

pub async fn prepare_follower_channel(
    remote_peer_id: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    //判断是否为自己
    if crate::is_self(remote_peer_id)? {
        return Err(anyhow::anyhow!("不允许本节点自身操作!"));
    }
    //判断是否存在
    let exist = peer_connection_exist(remote_peer_id)?;
    if exist {
        return Ok(get_peer_connection(remote_peer_id)?);
    }
    //新建
    let peer_connection = _prepare_follower_channel(remote_peer_id).await?;

    //插入
    push_peer_connection(remote_peer_id, peer_connection.clone())?;

    Ok(peer_connection)
}

pub async fn create_follower_channel(
    remote_peer_id: &String,
    remote_candidates: &Vec<String>,
    remote_local_description: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    //判断是否为自己
    if crate::is_self(remote_peer_id)? {
        return Err(anyhow::anyhow!("不允许本节点自身操作!"));
    }
    //判断是否存在
    let exist = peer_connection_exist(remote_peer_id)?;
    if !exist {
        //没有准备
        return Err(anyhow::anyhow!("需要提前准备!"));
    }
    //TODO判断是否是主叫，如果不是退出
    //新建
    let peer_connection =
        _create_follower_channel(remote_peer_id, remote_candidates, remote_local_description)
            .await?;

    Ok(peer_connection)
}

async fn _create_accept_channel(
    remote_peer_id: &String,
    remote_candidates: &Vec<String>,
    remote_local_description: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    // 创建数据通道
    let (peer_connection, sender, candidates) =
        new_answer_connection(remote_peer_id, remote_candidates, remote_local_description).await?;

    let local_description = get_local_description_string(peer_connection.clone()).await?;

    let data = serde_json::json!({
     "candidates": candidates,
     "local_description": local_description
    });

    let send_res = send_string(&serde_json::to_string(&serde_json::json!({
        "type": "relay",
        "data": {
            "type": "unicast",
            "data": {
                "peer_id": remote_peer_id,
                "data": {
                    "type": "webrtc",
                    "data": {
                        "type": "dial_response",
                        "data": data
                    }
                }
            }
        }
    }))?)
    .await;
    match send_res {
        Ok(_) => {
            tracing::debug!("发送成功!");
        }
        Err(err) => {
            tracing::error!("发送失败!{}", err);
        }
    }

    tracing::debug!("PeerConnection::new_answer......");
    let peer = PeerConnection::new_answer(remote_peer_id, remote_peer_id, sender, peer_connection);

    Ok(Arc::new(Mutex::new(peer)))
}

async fn _create_follower_channel(
    remote_peer_id: &String,
    remote_candidates: &Vec<String>,
    remote_local_description: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    let follower_connection = get_peer_connection(remote_peer_id)?;

    let peer_connection = {
        follower_connection
            .lock()
            .map_err(|err| anyhow::anyhow!("{}", err))?
            .agent
            .clone()
    };

    //设置远程
    let _ = set_remote_description_by_string(
        peer_connection.clone(),
        remote_local_description,
        remote_candidates,
    )
    .await?;

    //更新状态
    update_peer_connection(remote_peer_id, PeerConnectionState::Setuped)
}

async fn _prepare_follower_channel(
    remote_peer_id: &String,
) -> anyhow::Result<Arc<Mutex<PeerConnection>>> {
    // 创建agent
    let (peer_connection, sender, candidates) = new_offer_connection(remote_peer_id).await?;

    //TODO user_id
    let peer = PeerConnection::new_offer(
        remote_peer_id,
        remote_peer_id,
        sender,
        peer_connection.clone(),
    );

    let local_description = get_local_description_string(peer_connection.clone()).await?;

    let data = serde_json::json!({
     "candidates": candidates,
     "local_description": local_description,
    });

    let result = crate::signaling::send_string(&serde_json::to_string(&serde_json::json!({
        "type": "relay",
        "data": {
            "type": "unicast",
            "data": {
                "peer_id": remote_peer_id,
                "data": {
                    "type": "webrtc",
                    "data": {
                        "type": "dial",
                        "data": data
                    }
                }
            }
        }
    }))?)
    .await;

    match result {
        Ok(_) => {}
        Err(_) => {}
    }

    Ok(Arc::new(Mutex::new(peer)))
}
